import { Injectable, Logger } from '@nestjs/common';
import * as os from 'os';
import * as fs from 'fs';
import * as path from 'path';

export interface SystemMetrics {
  cpu: number;
  memory: number;
  disk: number;
  network: {
    in: number;
    out: number;
  };
  timestamp: number;
  processes: {
    total: number;
    running: number;
  };
  uptime: number;
  loadAverage: number[];
}

@Injectable()
export class MonitorService {
  private readonly logger = new Logger(MonitorService.name);
  private previousNetworkStats: any = null;
  private metricsHistory: SystemMetrics[] = [];
  private readonly maxHistorySize = 100; // 保存最近100个数据点

  async getSystemMetrics(): Promise<SystemMetrics> {
    const metrics: SystemMetrics = {
      cpu: await this.getCpuUsage(),
      memory: this.getMemoryUsage(),
      disk: await this.getDiskUsage(),
      network: await this.getNetworkUsage(),
      timestamp: Date.now(),
      processes: this.getProcessInfo(),
      uptime: os.uptime(),
      loadAverage: os.loadavg(),
    };

    // 保存到历史记录
    this.metricsHistory.push(metrics);
    if (this.metricsHistory.length > this.maxHistorySize) {
      this.metricsHistory.shift();
    }

    return metrics;
  }

  getMetricsHistory(duration: string = '1h'): SystemMetrics[] {
    const now = Date.now();
    let cutoffTime: number;

    switch (duration) {
      case '5m':
        cutoffTime = now - 5 * 60 * 1000;
        break;
      case '15m':
        cutoffTime = now - 15 * 60 * 1000;
        break;
      case '1h':
        cutoffTime = now - 60 * 60 * 1000;
        break;
      case '6h':
        cutoffTime = now - 6 * 60 * 60 * 1000;
        break;
      case '24h':
        cutoffTime = now - 24 * 60 * 60 * 1000;
        break;
      default:
        cutoffTime = now - 60 * 60 * 1000;
    }

    return this.metricsHistory.filter(metric => metric.timestamp >= cutoffTime);
  }

  private async getCpuUsage(): Promise<number> {
    return new Promise((resolve) => {
      const startMeasure = this.cpuAverage();
      
      setTimeout(() => {
        const endMeasure = this.cpuAverage();
        
        const idleDifference = endMeasure.idle - startMeasure.idle;
        const totalDifference = endMeasure.total - startMeasure.total;
        
        const percentageCPU = 100 - Math.floor(100 * idleDifference / totalDifference);
        resolve(Math.max(0, Math.min(100, percentageCPU)));
      }, 100);
    });
  }

  private cpuAverage() {
    const cpus = os.cpus();
    let user = 0, nice = 0, sys = 0, idle = 0, irq = 0;
    
    for (const cpu of cpus) {
      user += cpu.times.user;
      nice += cpu.times.nice;
      sys += cpu.times.sys;
      irq += cpu.times.irq;
      idle += cpu.times.idle;
    }
    
    return {
      idle: idle / cpus.length,
      total: (user + nice + sys + idle + irq) / cpus.length,
    };
  }

  private getMemoryUsage(): number {
    const totalMemory = os.totalmem();
    const freeMemory = os.freemem();
    const usedMemory = totalMemory - freeMemory;
    
    return Math.floor((usedMemory / totalMemory) * 100);
  }

  private async getDiskUsage(): Promise<number> {
    try {
      const stats = await fs.promises.statfs(process.cwd());
      const total = stats.blocks * stats.bavail;
      const available = stats.bavail * stats.bavail;
      const used = total - available;
      
      return Math.floor((used / total) * 100);
    } catch (error) {
      // 如果获取磁盘信息失败，返回模拟数据
      return Math.floor(Math.random() * 30) + 20; // 20-50%
    }
  }

  private async getNetworkUsage(): Promise<{ in: number; out: number }> {
    try {
      const networkInterfaces = os.networkInterfaces();
      let totalRx = 0;
      let totalTx = 0;

      // 这里简化处理，实际项目中可能需要读取 /proc/net/dev (Linux) 
      // 或使用其他方法获取网络流量统计
      for (const interfaceName in networkInterfaces) {
        const interfaces = networkInterfaces[interfaceName];
        if (interfaces) {
          for (const iface of interfaces) {
            if (!iface.internal) {
              // 模拟网络使用情况，实际应该从系统获取
              totalRx += Math.floor(Math.random() * 1000);
              totalTx += Math.floor(Math.random() * 1000);
            }
          }
        }
      }

      const currentStats = { rx: totalRx, tx: totalTx, timestamp: Date.now() };
      
      if (this.previousNetworkStats) {
        const timeDiff = (currentStats.timestamp - this.previousNetworkStats.timestamp) / 1000;
        const rxDiff = Math.max(0, currentStats.rx - this.previousNetworkStats.rx);
        const txDiff = Math.max(0, currentStats.tx - this.previousNetworkStats.tx);
        
        this.previousNetworkStats = currentStats;
        
        return {
          in: Math.floor(rxDiff / timeDiff / 1024), // KB/s
          out: Math.floor(txDiff / timeDiff / 1024), // KB/s
        };
      } else {
        this.previousNetworkStats = currentStats;
        return { in: 0, out: 0 };
      }
    } catch (error) {
      return { in: 0, out: 0 };
    }
  }

  private getProcessInfo() {
    try {
      // 在实际环境中，这里可以使用更精确的方法获取进程信息
      return {
        total: Math.floor(Math.random() * 200) + 100,
        running: Math.floor(Math.random() * 50) + 10,
      };
    } catch (error) {
      return { total: 0, running: 0 };
    }
  }

  async getSystemInfo() {
    return {
      platform: os.platform(),
      arch: os.arch(),
      release: os.release(),
      hostname: os.hostname(),
      cpus: os.cpus().length,
      totalMemory: Math.floor(os.totalmem() / 1024 / 1024 / 1024), // GB
      nodeVersion: process.version,
      uptime: os.uptime(),
    };
  }

  async getApplicationMetrics() {
    const memUsage = process.memoryUsage();
    
    return {
      pid: process.pid,
      uptime: process.uptime(),
      memoryUsage: {
        rss: Math.floor(memUsage.rss / 1024 / 1024), // MB
        heapTotal: Math.floor(memUsage.heapTotal / 1024 / 1024), // MB
        heapUsed: Math.floor(memUsage.heapUsed / 1024 / 1024), // MB
        external: Math.floor(memUsage.external / 1024 / 1024), // MB
      },
      cpuUsage: process.cpuUsage(),
    };
  }

  async getHealthCheck() {
    const metrics = await this.getSystemMetrics();
    const isHealthy = metrics.cpu < 90 && metrics.memory < 90 && metrics.disk < 95;
    
    return {
      status: isHealthy ? 'healthy' : 'unhealthy',
      timestamp: Date.now(),
      checks: {
        cpu: {
          status: metrics.cpu < 90 ? 'pass' : 'fail',
          value: metrics.cpu,
          threshold: 90,
        },
        memory: {
          status: metrics.memory < 90 ? 'pass' : 'fail',
          value: metrics.memory,
          threshold: 90,
        },
        disk: {
          status: metrics.disk < 95 ? 'pass' : 'fail',
          value: metrics.disk,
          threshold: 95,
        },
      },
    };
  }

  // 日志分析
  async getLogAnalysis() {
    try {
      // 这里可以分析应用日志文件
      // 为演示目的，返回模拟数据
      return {
        errorCount: Math.floor(Math.random() * 10),
        warningCount: Math.floor(Math.random() * 20),
        infoCount: Math.floor(Math.random() * 100) + 50,
        totalRequests: Math.floor(Math.random() * 1000) + 500,
        averageResponseTime: Math.floor(Math.random() * 100) + 50,
        slowQueries: Math.floor(Math.random() * 5),
      };
    } catch (error) {
      this.logger.error('Failed to analyze logs', error);
      return {
        errorCount: 0,
        warningCount: 0,
        infoCount: 0,
        totalRequests: 0,
        averageResponseTime: 0,
        slowQueries: 0,
      };
    }
  }
}